package com.study.demo.upload;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.study.demo.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 文档：https://help.aliyun.com/document_detail/31926.html
 * @author liuhongzhen
 */
@Slf4j
public class OssService {

    //阿里云pdf文件存储目录
    private static final String PAPER_PDF_DIR = "paper_pdf/";

    /**
     * AccessKey ID
     * LTAI5tHMu7By2JPDBMjrRT2g
     * <p>
     * AccessKey Secret
     * 5u9eazYeKc1lBFVxbUAFygBW4jWoj5
     */
    private static final String BUCKET_NAME = "wegrowx-platform";

    private static final String ENDPOINT = "oss-cn-beijing.aliyuncs.com";

    private static final String OSS_ACCESS_ID = "LTAI5tHMu7By2JPDBMjrRT2g";

    private static final String OSS_ACCESS_SECRET = "5u9eazYeKc1lBFVxbUAFygBW4jWoj5";

    /**
     * 生成签名
     *
     * @param dir
     * @return
     */
    public static Map<String, String> generateSign(String dir) {

        String host = "https://" + BUCKET_NAME + "." + ENDPOINT;
        OSS ossClient = new OSSClient(ENDPOINT, OSS_ACCESS_ID, OSS_ACCESS_SECRET);

        long expireTime = 30;
        long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
        Date expiration = new Date(expireEndTime);
        PolicyConditions policyConds = new PolicyConditions();
        policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
        policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

        String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
        byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
        String encodedPolicy = BinaryUtil.toBase64String(binaryData);
        String postSignature = ossClient.calculatePostSignature(postPolicy);
        ossClient.shutdown();


        Map<String, String> respMap = new LinkedHashMap<>();
        respMap.put("accessId", OSS_ACCESS_ID);
        respMap.put("region", "oss-cn-beijing");
        respMap.put("bucketName", BUCKET_NAME);
        respMap.put("policy", encodedPolicy);
        respMap.put("signature", postSignature);
        respMap.put("dir", dir);
        respMap.put("host", host);
        respMap.put("expire", String.valueOf(expireEndTime / 1000));
        respMap.put("uniqueName", UUID.randomUUID().toString().replace("-", ""));

        return respMap;
    }

    /**
     * 上传文件
     */
    public static String uploadFile(String filename) {

        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, OSS_ACCESS_ID, OSS_ACCESS_SECRET);
        InputStream inputStream = null;
        try {
            //获取文件流
            inputStream = new FileInputStream(filename);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //1.在文件名称中添加随机唯一的值
        String uuid = UUIDUtils.getId();
        //2.把文件按日期分类
        LocalDate localDate = LocalDate.now();
        DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String datePath = localDate.format(localDateFormatter);

        String ossFilename = PAPER_PDF_DIR + datePath + "/" + uuid + ".pdf";

        //调用OSS方法实现上传
        ossClient.putObject(BUCKET_NAME, ossFilename, inputStream);

        //无论是否上传成功，删除本地文件
        delFile(filename);

        //把上传之后的文件路径返回
        //需要把上传到阿里云oss路径手动拼接出来
        //路径规则：https://edu-cgq.oss-cn-chengdu.aliyuncs.com/QQ%E5%9B%BE%E7%89%8720200502111905.jpg
        String url = "https://" + BUCKET_NAME + "." + ENDPOINT + "/" + ossFilename;
        //判断是否已经上传成功，然后删除本地的文件
        boolean exist = ossClient.doesObjectExist(BUCKET_NAME,ossFilename);

        ossClient.shutdown();
        if (exist){
            return url;
        }
        return "";
    }

    /**
     * 删除文件
     */
    public static void delFile(String filename) {

        File myObj = new File(filename);
        if (myObj.delete()) {
            log.info("#OssService.delFile.success# filename:{}",filename);
        } else {
            log.info("#OssService.delFile.failed# filename:{}",filename);
        }
    }
}
